from typing import List, Dict, Any
from datetime import datetime, timedelta
from fastapi import APIRouter, Depends, HTTPException, Body, Query, Path, status
from fastapi.security import OAuth2PasswordRequestForm
from sqlalchemy.ext.asyncio import AsyncSession
from jose import jwt
from passlib.context import CryptContext
from app.cache.decorators import invalidate_cache

from app.database import get_db
from app.schemas.schemas import (
    ResponseBase, SchoolCreate, SchoolResponse, ClassCreate, 
    ClassResponse, CourseCreate, CourseResponse, AuthResponse,
    TokenResponse, UserInfo, UserCreate,UserAuth,ClassDetailResponse,
    ClassAllListResponse, CourseAllListResponse
)
from app.models.models import User
from app.crud import crud_school, crud_class, crud_course, crud_user
from app.api.deps import get_current_admin
from app.config import settings
from app.utils.logging import get_logger

# 创建API路由
router = APIRouter(prefix="/api/v1/admin")

# 创建日志记录器
logger = get_logger(__name__)

# 密码哈希工具
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")

# 创建访问令牌
def create_access_token(data: dict, expires_delta: timedelta = None):
    to_encode = data.copy()
    if expires_delta:
        expire = datetime.utcnow() + expires_delta
    else:
        expire = datetime.utcnow() + timedelta(minutes=15)
    to_encode.update({"exp": expire})
    encoded_jwt = jwt.encode(to_encode, settings.secret_key, algorithm=settings.algorithm)
    return encoded_jwt

@router.post("/auth/register", response_model=ResponseBase, status_code=200)
async def register_admin(
    user: UserCreate,
    db: AsyncSession = Depends(get_db)
):
    """
    管理员注册
    """
    # 验证密钥
    secret_key = "8db4ac6283983e09238909929dcf1284aa62ef695f983b2d860cc9d0988bf403"
    if user.secret_key != secret_key:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="密钥不正确"
        )
    
    # 检查用户名是否已存在
    db_user = await crud_user.get_user_by_username(db, user.username)
    if db_user:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="用户名已存在"
        )
    
    # 创建新用户
    new_user = await crud_user.create_user(db, user)
    
    return {
        "code": 201,
        "data": {
            "id": new_user.id,
            "username": new_user.username,
            "role": new_user.role,
            "created_at": new_user.created_at
        },
        "message": "管理员账号创建成功"
    }

@router.post("/auth/login", response_model=AuthResponse)
async def login_for_access_token(
    user_credentials: UserAuth,
    db: AsyncSession = Depends(get_db)
):
    """
    用户登录
    """
    # 验证用户
    user = await crud_user.authenticate_user(db, user_credentials.username, user_credentials.password)
    if not user:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="用户名或密码错误",
            headers={"WWW-Authenticate": "Bearer"},
        )
    
    # 创建访问令牌
    access_token_expires = timedelta(minutes=settings.access_token_expire_minutes)
    access_token = create_access_token(
        data={"sub": str(user.id)},
        expires_delta=access_token_expires
    )
    
    return {
        "code": 200,
        "data": {
            "token": access_token,
            "expires_in": settings.access_token_expire_minutes * 60,
            "user": {
                "id": user.id,
                "username": user.username,
                "role": user.role
            }
        },
        "message": "success"
    }

@router.post("/schools", response_model=ResponseBase, status_code=200)
@invalidate_cache(pattern="cache:schools:*")
async def create_school(
    school: SchoolCreate,
    db: AsyncSession = Depends(get_db),
    current_user: User = Depends(get_current_admin)
):
    """
    创建学校
    """
    db_school = await crud_school.create_school(db, school)
    return {
        "code": 201,
        "data": db_school,
        "message": "success"
    }

@router.post("/classes", response_model=ClassDetailResponse, status_code=200)
@invalidate_cache(pattern="cache:classes:*")
async def create_class(
    class_obj: ClassCreate,
    db: AsyncSession = Depends(get_db),
    current_user: User = Depends(get_current_admin)
):
    """
    创建班级
    """
    db_class = await crud_class.create_class(db, class_obj)
    return {
        "code": 201,
        "data": db_class,
        "message": "success"
    }

@router.post("/courses", response_model=ResponseBase, status_code=200)
@invalidate_cache(pattern="cache:class_courses:*")
async def create_course(
    courses: List[CourseCreate],
    db: AsyncSession = Depends(get_db),
    current_user: User = Depends(get_current_admin)
):
    """
    批量创建或更新课程：接收多个 CourseCreate
    """
    results = []
    for course in courses:
        db_course, action = await crud_course.upsert_course(db, course)
        results.append({
            "record": db_course,
            "action": action
        })
    return {
        "code": 200,
        "data": results,
        "message": "批量处理成功"
    }


@router.get("/classes/all", response_model=ClassAllListResponse)
async def get_all_classes_admin(
    school_id: int | None = Query(None, description="学校ID，可选，用于按学校过滤"),
    db: AsyncSession = Depends(get_db),
    current_user: User = Depends(get_current_admin)
):
    """
    管理员获取全部班级（不分页，可按学校ID过滤）
    """
    classes = await crud_class.get_all_classes(db, school_id)
    classes_response = [ClassResponse.model_validate(c) for c in classes]
    return {
        "code": 200,
        "data": classes_response,
        "message": "success"
    }


@router.get("/courses/all", response_model=CourseAllListResponse)
async def get_all_courses_admin(
    class_id: int | None = Query(None, description="按班级ID过滤，可选"),
    class_code: str | None = Query(None, description="按班级编号过滤，可选"),
    db: AsyncSession = Depends(get_db),
    current_user: User = Depends(get_current_admin)
):
    """
    管理员获取全部课程（不分页，可按 class_id 或 class_code 过滤）
    """
    courses = await crud_course.get_all_courses(db, class_id=class_id, class_code=class_code)
    # 直接返回 ORM -> Pydantic
    courses_response = [CourseResponse.model_validate(c) for c in courses]
    return {
        "code": 200,
        "data": courses_response,
        "message": "success"
    }
